#_*_ coding: UTF-8 _*_

import sys
from PyQt4 import QtCore, QtSql, QtGui
from classes import *
from ui_basic_classes import MainView, NiceTextEdit
from servers.page_number.definitions import *
from servers.translation.definitions import *
from core import uicomponents,qpath,log
import servers.quran.definitions

class QuranMainView(MainView):
	def __init__(self, parent=None):
		MainView.__init__(self, parent)
	
		#real ui components are constructed here
		self.quran = NiceTextEdit()
		self.quran.setReadOnly(True)
		self.quran.setFont(QtGui.QFont('B Badr', 18,QtGui.QFont.Normal))
		self.quran.contextMenuEvent = self.contextMenuEvent
		QtCore.QObject.connect(self.quran, QtCore.SIGNAL("selectionChanged()"), self.selectionControl)

		QtCore.QObject.connect(self.quran, QtCore.SIGNAL("nextAye()"), self.nextAye)
		QtCore.QObject.connect(self.quran, QtCore.SIGNAL("prevAye()"), self.prevAye)
		QtCore.QObject.connect(self.quran, QtCore.SIGNAL("nextPage()"), self.nextPage)
		QtCore.QObject.connect(self.quran, QtCore.SIGNAL("prevPage()"), self.prevPage)
		QtCore.QObject.connect(self.quran, QtCore.SIGNAL("nextWord()"), self.nextWord)
		QtCore.QObject.connect(self.quran, QtCore.SIGNAL("prevWord()"), self.prevWord)

		self.soorehSelector = QtGui.QComboBox()
		self.soorehSelector.setFixedWidth(100)
		for theSooreh in Quran.getAllSooreh():
			self.soorehSelector.addItem(theSooreh.name.decode('utf8'))     
		
		self.ayeSelector = QtGui.QSpinBox()
		self.ayeSelector.setRange(1,1)
		self.ayeSelector.setFixedWidth(50)
		
		self.safheSelector = QtGui.QSpinBox()
		self.safheSelector.setRange(1, 604)   #quran has 604 pages
		self.safheSelector.setFixedWidth(50)
		
		self.refreshButton = QtGui.QPushButton(u"تازه سازي")
		QtCore.QObject.connect(self.refreshButton,QtCore.SIGNAL("clicked()"),self.refreshWithPath)

		#components are layed out here
		loQuranSelector = QtGui.QHBoxLayout()
		loQuranSelector.addWidget(QtGui.QLabel(u'سوره'))
		loQuranSelector.addWidget(self.soorehSelector)
		loQuranSelector.addWidget(QtGui.QLabel(u'آيه'))
		loQuranSelector.addWidget(self.ayeSelector)
		loQuranSelector.addWidget(QtGui.QLabel(u'صفحه'))
		loQuranSelector.addWidget(self.safheSelector)
		loQuranSelector.addStretch()
		loQuranSelector.addWidget(self.refreshButton)
		
		loQuran = QtGui.QVBoxLayout()
		loQuran.addLayout(loQuranSelector)
		loQuran.addWidget(self.quran)
		
		self.setLayout(loQuran)
		
		QtCore.QObject.connect(self.soorehSelector, QtCore.SIGNAL('currentIndexChanged(int)'), self.gotoSoorehZ)
		QtCore.QObject.connect(self.ayeSelector, QtCore.SIGNAL('valueChanged(int)'), self.gotoAyeInSure)
		QtCore.QObject.connect(self.safheSelector, QtCore.SIGNAL('valueChanged(int)'), self.gotoSafhe)
		self.sooreh = None
	
	def prevWord(self):
		a = self.quran.textCursor()
		a.movePosition(QtGui.QTextCursor.PreviousWord)
		a.movePosition(QtGui.QTextCursor.PreviousWord)
		a.select(QtGui.QTextCursor.WordUnderCursor)
		self.quran.setTextCursor(a)
		try:
			self.selectionControl()
		except:
			a = self.quran.textCursor()
			a.movePosition(QtGui.QTextCursor.PreviousWord)
			a.movePosition(QtGui.QTextCursor.PreviousWord)
			a.movePosition(QtGui.QTextCursor.PreviousWord)			
			a.select(QtGui.QTextCursor.WordUnderCursor)
			self.quran.setTextCursor(a)
			self.selectionControl()
		self.quran.emit(QtCore.SIGNAL("selectionChanged()"))

	def nextWord(self):
		a = self.quran.textCursor()
		a.movePosition(QtGui.QTextCursor.NextWord)
		a.select(QtGui.QTextCursor.WordUnderCursor)
		self.quran.setTextCursor(a)
		try:
			self.selectionControl()
		except:
			a = self.quran.textCursor()
			a.movePosition(QtGui.QTextCursor.NextWord)
			a.select(QtGui.QTextCursor.WordUnderCursor)
			self.quran.setTextCursor(a)
			self.selectionControl()
		self.quran.emit(QtCore.SIGNAL("selectionChanged()"))

	def prevPage(self):
		self.gotoSafhe(self.curPage.prev().page_number)
		a = self.quran.textCursor()
		a.movePosition(QtGui.QTextCursor.End)
		a.select(QtGui.QTextCursor.WordUnderCursor)
		self.quran.setTextCursor(a)
		self.selectionControl()
		self.quran.emit(QtCore.SIGNAL("selectionChanged()"))		
		
	def nextPage(self):
		self.gotoSafhe(self.curPage.next().page_number)
		a = self.quran.textCursor()
		a.movePosition(QtGui.QTextCursor.Start)
		a.select(QtGui.QTextCursor.WordUnderCursor)
		self.quran.setTextCursor(a)
		self.selectionControl()
		self.quran.emit(QtCore.SIGNAL("selectionChanged()"))		

	def showPage(self,page):
		self.curPage = page
		log.logger.debug('quranMainView.showPage(%d)' % page.page_number)
		uicomponents.SharedUi.busyDialog.tellBusy(u'راه اندازي صفحه...')
		self.ayat = [page_aye.aye for page_aye in page.page_ayat]
		self.soorehs = [sure for sure in set([aye.sure for aye in self.ayat])]
		safheMatn = QtCore.QString()
		for aye in self.ayat:
			session.refresh(aye)
			ayeMatn = ""
			for word in aye.words:
				session.refresh(word)
				w = word.word
				for mask in servers.quran.definitions.quranWordViewMasks:
					w = servers.quran.definitions.quranWordMasks[mask](word,w)
				for commenter in servers.quran.definitions.quranWordViewCommenters:
					w = servers.quran.definitions.quranWordCommenters[commenter](word,w)
				ayeMatn += w + " "
			if (aye.n == 1) and not(aye==self.ayat[0]):
				safheMatn.append(u'<br>')
			safheMatn.append(u'%s<b>(%d)</b><a name="X%d"></a> ' % (ayeMatn.decode('utf8'), aye.n, aye.n))
		self.quran.setHtml('<div dir=rtl>'+safheMatn+'</div>')	
		uicomponents.SharedUi.busyDialog.tellDone()

	def showSooreh(self, sooreh):
		log.logger.debug('quranMainView.showSooreh(%d)' % sooreh.id)
		uicomponents.SharedUi.busyDialog.tellBusy(u'لطفا چند لحظه صبر کنید...')
		self.ayat = list(sooreh.ayat)
		soorehMatn = QtCore.QString()
		for aye in self.ayat:
			soorehMatn.append(u'%s<b>(%d)</b><a name="X%d"></a> ' % (aye.data.data.decode('utf8'), aye.n, aye.n))
		self.quran.setHtml('<div dir=rtl>'+soorehMatn+'</div>')
		uicomponents.SharedUi.busyDialog.tellDone()

	def gotoSoorehZ(self, soorehNumber,showit=True):
		log.logger.debug('quranMainView.gotoSoorehZ('+str(soorehNumber) + str(showit)+')')
		self.sooreh = Quran.getSoorehByNumber(soorehNumber+1)
		#self.showSooreh(self.sooreh)
		if showit:
			self.showPage(self.sooreh.ayat[0].page.page)

		self.ayeSelector.blockSignals(True)
		self.ayeSelector.setRange(1, len(self.sooreh.ayat))
		self.ayeSelector.blockSignals(False)

		self.safheSelector.blockSignals(True)
		self.safheSelector.setValue(self.sooreh.ayat[0].page.page_number)
		self.safheSelector.blockSignals(False)
		
		self.soorehSelector.blockSignals(True)
		self.soorehSelector.setCurrentIndex(soorehNumber)
		self.soorehSelector.blockSignals(False)

	def gotoSafhe(self, number):
		log.logger.debug('quranMainVire.gotoSafhe(%d)' % number)
		safhe = page_query.get(number)
		targetSooreh = safhe.page_ayat[0].aye.sure
		
		self.gotoSoorehZ(targetSooreh.id-1,False)
		self.gotoAye(safhe.page_ayat[0].aye)
		self.safheSelector.blockSignals(True)
		self.safheSelector.setValue(number)
		self.safheSelector.blockSignals(False)
	
	def gotoAyeInSure(self,aye_n):
		log.logger.debug('quranMainView.goroAyeInSure(%d)' % aye_n)
		self.gotoAye(self.sooreh.ayat[aye_n-1])


	def nextAye(self):
		self.gotoAye(self.curAye.next())
		
	def prevAye(self):
		self.gotoAye(self.curAye.prev())

	def gotoAye(self, aye,showit=True):
		self.curAye = aye
		log.logger.debug('quranMainView.gotoAye(%s : %s , %s )' % (str(aye.sure.id), str(aye.n), str(showit)))
		if showit:
			self.showPage(aye.page.page)
			self.quran.scrollToAnchor(u'X%d' % aye.n)
		else:	
			self.quran.scrollToAnchor(u'X%d' % aye.n)
		
		self.soorehSelector.blockSignals(True)
		self.soorehSelector.setCurrentIndex(aye.sure.id-1)
		self.soorehSelector.blockSignals(False)

		self.ayeSelector.blockSignals(True)
		self.ayeSelector.setValue(aye.n)
		self.ayeSelector.blockSignals(False)

		self.safheSelector.blockSignals(True)
		self.safheSelector.setValue(aye.page.page.page_number)
		self.safheSelector.blockSignals(False)

	def getSelectionType(self):
		log.logger.debug('quranMainView.getSelectionType()')
		endSelect, startSelect = self.quran.textCursor().selectionFragmentLabelAndWordOffset()

		stAyeN = startSelect[1]
		if (stAyeN==u'') and (startSelect[0]!=0):
			stAyeN = 0
		elif (stAyeN==u''):
			stAyeN = self.ayat[0].n - 1
		else:	
			stAyeN = int(stAyeN)

		edAyeN = endSelect[1]
		if (edAyeN==u'') and (endSelect[0]!=0):
			edAyeN = 0
		elif(edAyeN==u''):
			edAyeN = self.ayat[0].n - 1
		else:
			edAyeN = int(edAyeN)
			
		endSelectWord = endSelect[2]
		startSelectWord = startSelect[2]
		
		log.logger.debug(endSelect)
		log.logger.debug(edAyeN)
		log.logger.debug(endSelectWord)
		
		startWord = self.soorehs[endSelect[0]].ayat[stAyeN].words[startSelectWord]

		if edAyeN >= len(self.soorehs[endSelect[0]].ayat):
			edAyeN = -1
			endSelectWord = -1
		if endSelectWord >= len(self.soorehs[endSelect[0]].ayat[edAyeN].words):
			endSelectWord = -1
		endWord = self.soorehs[endSelect[0]].ayat[edAyeN].words[endSelectWord]
		
		
		self.gotoAye(startWord.aye,False)

		return uicomponents.Selection.selectionType(startWord, endWord)

	def selectionControl(self):
		self.getSelectionType()

	def refreshWithPath(self):
		self.gotoAyeInSure(self.ayeSelector.value())
	def contextMenuEvent(self, event): #very strangely this is run in scope of QuranMainView rather than NiceTextEdit though giving the function to NiceTextEdit!
		selectionType = self.getSelectionType()

		if selectionType==uicomponents.Selection.Word:
			uicomponents.SharedUi.wordPopupMenu.exec_(event.globalPos())
		elif selectionType==uicomponents.Selection.Aye:
			uicomponents.SharedUi.ayePopupMenu.exec_(event.globalPos())
		elif selectionType==uicomponents.Selection.Part:
			uicomponents.SharedUi.selectionPopupMenu.exec_(event.globalPos())

class QuranSearchResultView(MainView):

	def __init__(self, parent=None,qBrowser=None):
		MainView.__init__(self, parent)
		self.quranBrowser = qBrowser
		#real ui components are constructed here
		self.quran = NiceTextEdit()
		self.quran.setReadOnly(True)
		self.quran.setFont(QtGui.QFont('B Badr', 18))
		self.quran.mouseDoubleClickEvent = self.mouseDoubleClickEvent

		
		#components are layed out here
		loResults = QtGui.QVBoxLayout()
		loResults.addWidget(self.quran)
		
		self.setLayout(loResults)
	
	def showResults(self, ayatWithHighlights):
		self.ayatWithHighlight = ayatWithHighlights
		
		wholeHtml = QtCore.QString()
		
		for awh in self.ayatWithHighlight:
			aye = awh[0]
			ayeWords = aye.words
			ayeHLs = awh[1]
			
			ayeText = QtCore.QString(u'<p dir=rtl style="font-size: 18pt; font-family: B Badr;">')
			counter = 0
			for aHighlight in ayeHLs:
				while counter+1 < aHighlight:
					ayeText.append(QtCore.QString.fromUtf8(' %s ' % ayeWords[counter].word))
					counter = counter + 1
				ayeText.append(QtCore.QString.fromUtf8(' <font style="background-color: #aaccff; font-weight: 700;">%s</font> ' % ayeWords[counter].word))
				counter = counter + 1
			while counter < len(aye.words):
				ayeText.append(QtCore.QString.fromUtf8(' %s ' % ayeWords[counter].word))
				counter = counter + 1

			ayeText.append(QtCore.QString.fromUtf8('<a style="text-decoration: none;" name="SureId" href="%d"><b>[%s %d] ص %d</b></a><br>' % (aye.id, aye.sure.name, aye.n, aye.page.page_number)))

			ayeText.append(QtCore.QString.fromUtf8('<font style="font-size:14pt; " face="B Nazanin">%s</font>' % aye.translation.fa))

			ayeText.append(QtCore.QString.fromUtf8('<br>--------------------------------------------------------</p>'))
			
			wholeHtml.append(ayeText)
			
		self.quran.setHtml(wholeHtml)


	def mouseDoubleClickEvent(self, event): #very strangely this is run in scope of QuranSearchResultView rather than NiceTextEdit though giving the function to NiceTextEdit!
		ayeNumber = self.quran.textCursor().charFormat().anchorHref()
		try:
			aye = qpath.aye_query.get(int(ayeNumber))
			servers.quran.ui.quranBrowser.quran.gotoAye(aye)
		except a:
			print "Error:%s" % a[1]

		try:
			QtGui.QTextEdit.mouseDoubleClickEvent(self.quran, event)
		except a:
			print "Error:%s" % a[1]

class QuranSearchDialog:
	def __init__(self, parent=None):
		self.dialog = QtGui.QDialog(parent, QtCore.Qt.WindowTitleHint | QtCore.Qt.WindowSystemMenuHint)
		self.dialog.setWindowTitle(u'جستجو در قرآن')
		
		self.expression = QtGui.QLineEdit()
		self.wholeWord = QtGui.QCheckBox(u'کلمه کامل')
		self.withErab = QtGui.QCheckBox(u'با اعراب')
		self.quranScope = QtGui.QComboBox()
		self.quranScope.addItem(u'قرآن')
		self.quranScope.addItem(u'سوره')
		
		QtCore.QObject.connect(self.expression, QtCore.SIGNAL('returnPressed()'), self.dialog.accept)

		loRow2 = QtGui.QHBoxLayout()
		loRow2.addWidget(self.wholeWord)
		loRow2.addWidget(self.withErab)
		
		loRow3 = QtGui.QHBoxLayout()
		loRow3.addWidget(QtGui.QLabel(u'محدوده جستجو'))
		loRow3.addWidget(self.quranScope)
		#loRow3.addStretch()
		
		loSearch = QtGui.QVBoxLayout()
		loSearch.addWidget(self.expression)
		loSearch.addLayout(loRow2)
		loSearch.addLayout(loRow3)
		
		self.dialog.setLayout(loSearch)
		
	def show(self):
		self.res = self.dialog.exec_()
		return self.res
	
	def getSearchParams(self):
		"""Returns expression, wholeWord, withErab, quranScope"""
		if not hasattr(self, 'res') or self.res!=QtGui.QDialog.Accepted:
			raise Exception('dialog (still) has no results!')
		
		return self.expression.text(), self.wholeWord.isChecked(), self.withErab.isChecked(), self.quranScope.currentIndex()==0


class QuranAdvancedSearchDialog:
	def __init__(self, parent=None):
		self.dialog = QtGui.QDialog(parent, QtCore.Qt.WindowTitleHint | QtCore.Qt.WindowSystemMenuHint)
		self.dialog.setWindowTitle(u'جستجوی پیشرفته')
		
		

		self.expression = QtGui.QLineEdit()
		self.expression.setLayoutDirection(QtCore.Qt.LeftToRight)
		QtCore.QObject.connect(self.expression, QtCore.SIGNAL('returnPressed()'), self.dialog.accept)

		self.okButton = QtGui.QPushButton(u'جستجو')
		QtCore.QObject.connect(self.okButton, QtCore.SIGNAL('clicked()'), self.dialog.accept)

		servers.quran.definitions.advSearchQuery['widget'] = self.expression
		self.loSearch = QtGui.QVBoxLayout()
		self.dialog.setLayout(self.loSearch)		

	def design(self):
		if self.loSearch.count() == 0:
			self.loSearch.addWidget(self.expression)
			for plugin in servers.quran.definitions.advSearchPlugins.items():
				self.loSearch.addLayout(plugin[1]['layout'])
			self.loSearch.addWidget(self.okButton)	
	def show(self):
		self.design()
		self.res = self.dialog.exec_()
		return self.res
	
	def getSearchParams(self):
		"""Returns expression, wholeWord, withErab, quranScope"""
		if not hasattr(self, 'res') or self.res!=QtGui.QDialog.Accepted:
			raise Exception('dialog (still) has no results!')
		
		return self.expression.text()


class QuranWithTranslactionView(MainView):
	def __init__(self, parent=None):
		MainView.__init__(self, parent)
	
		#real ui components are constructed here
		self.quran = QuranMainView(parent)
		self.translation = NiceTextEdit()

		layout = QtGui.QVBoxLayout()
		layout.addWidget(self.translation)
		frame = QtGui.QFrame()
		frame.setLayout(layout)

		loBoth = QtGui.QVBoxLayout()
		loBoth.addWidget(self.quran)
		loBoth.addWidget(frame)
		
		self.setLayout(loBoth)
		
		QtCore.QObject.connect(self.quran.soorehSelector, QtCore.SIGNAL('currentIndexChanged(int)'), self.transGotoSoorehZ)
		QtCore.QObject.connect(self.quran.ayeSelector, QtCore.SIGNAL('valueChanged(int)'), self.transGotoAye)
		QtCore.QObject.connect(self.quran.safheSelector, QtCore.SIGNAL('valueChanged(int)'), self.transGotoSafhe)
		
		#self.quran.quran.scrollContentsBy = self.OR_scrollContentsBy
		
		self.transGotoSoorehZ(0)
		
	def transShowSooreh(self, sooreh):
		realAyat = list(sooreh.ayat)
		self.ayat = [aye.translation for aye in realAyat]
		soorehMatn = QtCore.QString()
		counter = 1
		for aye in self.ayat:
			soorehMatn.append(u'%s<b>(%d)</b><a name="X%d"></a> ' % (aye.fa.decode('utf8'), counter, counter))
			counter = counter + 1
		self.translation.setHtml('<div dir=rtl style="font-family: B Nazanin; font-size:14pt">'+soorehMatn+'</div>')

	def transGotoSoorehZ(self, soorehNumber):
		self.sooreh = Quran.getSoorehByNumber(soorehNumber+1)
		self.transShowSooreh(self.sooreh)

	def transGotoSafhe(self, number):
		safhe = page_query.get(number)
		targetSooreh = safhe.page_ayat[0].aye.sure
		if targetSooreh is not self.sooreh:
			idx = targetSooreh.id-1
			self.transGotoSoorehZ(idx)

		self.transGotoAye(safhe.page_ayat[0].aye.n)
		
	def transGotoAye(self, numberInSooreh):
		self.translation.scrollToAnchor(u'X%d' % numberInSooreh)
		
	#def OR_scrollContentsBy(self, dx, dy): #This is run in QuranMainView but uses this!!!
		#QtGui.QTextEdit.scrollContentsBy(self.quran.quran, dx, dy)
		
		#self.translation.scrollContentsBy(dx, dy)
		
